﻿using XYAC.Framework.MonitorTireMaterialOnline.Entities;

namespace XYAC.Framework.MonitorTireMaterialOnline.DataExporter
{
    // Class representing the entire data file
    public class DataFile
    {
        public float FileInertvaWidth { get; set; }
        public double XReference { get; set; }
        public List<MeasureKey> MeasureKeys { get; set; }
        public string TypeName { get; set; }
        public int ID { get; set; }
        public List<StableKeys> StableKeys { get; set; }
        public float MeasureLeftArea { get; set; }
        public float MeasureRightArea { get; set; }
        public float MeasureArea { get; set; }
        public float Area { get; private set; }
        public float LeftArea { get; private set; }
        public float RightArea { get; private set; }
        public ClsMyNominal SpecStable { get; private set; }

        public static DataFile FromSpecVal(SpecValTable specVal)
        {
            try
            {


                if (specVal == null)
                    throw new ArgumentNullException(nameof(specVal));

                ClsMyNominal nominalData = new ClsMyNominal((NominalType)Enum.Parse(typeof(NominalType), specVal.ProfileType.ToString()));
                // 初始化 ClsMyNominal 
                nominalData.SetInitInfo(
                    specVal.ProfileName,
                    specVal.TotalWidth.Value,
                    specVal.WidthTol.Value,
                    specVal.RimHeight.Value,
                    specVal.RimTol.Value,
                    specVal.AreaDiff.Value,
                    specVal.GJD,
                    specVal.TextNo,
                    specVal.ShoulderWidth.Value,
                    specVal.ShoulderWidthTol.Value,
                    specVal.ShoulderHeight.Value,
                    specVal.ShoulderHeightTol.Value,
                    specVal.DateTimePicker,
                    specVal.jiao,
                    specVal.ResultPercent.Value,
                    CenterType.Lowest // 根据实际需求调整
                );

                // 解析 SpecValData 和 BottomHeightVals
                List<float> thicknessList;
                List<float> bottomHeightList;

                try
                {
                    thicknessList = ClsMyMeasuring.HeightListFromStr(specVal.SpecVal);
                    bottomHeightList = ClsMyMeasuring.BottomListFromStr(specVal.BottomHeightVals);

                }
                catch (Exception ex)
                {
                    // 处理解析错误
                    throw new InvalidOperationException("Error parsing measurement data.", ex);
                }

                // 创建 MeasurDataList
                List<Measuring.MeasurData> measurDataList = new List<Measuring.MeasurData>();
                long count = Math.Min(thicknessList.Count, bottomHeightList.Count);
                for (int i = 0; i < count; i++)
                {
                    measurDataList.Add(new Measuring.MeasurData(thicknessList[i], bottomHeightList[i]));
                }

                // 解析 TestResult
                MeasureResult result = ClsMyMeasuring.MeasureResultFromStr(specVal.TestResult);

                // 初始化 ClsMyMeasuring
                ClsMyMeasuring measureData = new ClsMyMeasuring(measurDataList, specVal.IntervalWidth.Value, result)
                {
                    XReference = specVal.IXReference.Value,
                    KeyPoints = ClsMyMeasuring.KeyPointsFromStr(specVal.KeyPoints),
                    BanZu = specVal.BanZu,

                };



                DataFile dataFile = new DataFile()
                {
                    FileInertvaWidth = specVal.IntervalWidth.Value,
                    StableKeys = nominalData.KeyPoints.Select(T => new DataExporter.StableKeys() { Coordinate = T.Point.X, Value = T.Point.Y }).ToList(),
                    ID = specVal.ID.Value,
                    MeasureKeys = measureData.KeyPoints.Select(T => new DataExporter.MeasureKey() { Coordinate = T.Point.X, Value = T.Point.Y }).ToList(),
                    SpecStable = nominalData,
                    XReference = specVal.IXReference.Value,
                    TypeName = specVal.ProfileName,
                    MeasureLeftArea = measureData.LeftArea,
                    MeasureRightArea = measureData.RightArea,
                    MeasureArea = measureData.Area,
                    Area = nominalData.Area,
                    LeftArea = nominalData.LeftArea,
                    RightArea = nominalData.RightArea,
                };

                return dataFile;
            }
            catch (Exception)
            {
                return null;
            }
        }
        private static List<Point> ConvertToPoints(ClsMyMeasuring myMeasuring)
        {
            var points = new List<Point>();
            int count = Math.Min(myMeasuring.ThicknessPoints.Count, myMeasuring.BottomHeightPoints.Count);

            for (int i = 0; i < count; i++)
            {
                var point = new Point
                {
                    Index = i,
                    X = myMeasuring.ThicknessPoints[i].Point.Y,
                    Y = myMeasuring.BottomHeightPoints[i].Point.Y
                };
                points.Add(point);
            }

            return points;
        }
        public DataFile()
        {
            MeasureKeys = new List<MeasureKey>();
            StableKeys = new List<StableKeys>();
        }
        /// <summary>
        /// 验证 DataFile 对象的完整性和有效性。
        /// </summary>
        /// <param name="errors">包含所有验证错误信息的列表。</param>
        /// <returns>如果验证成功，则返回 true；否则返回 false。</returns>
        public bool Validate(out List<string> errors)
        {
            errors = new List<string>();

            // 验证集合是否为空 

            if (MeasureKeys == null || MeasureKeys.Count == 0)
                errors.Add("MeasureKeys 集合不能为空且必须包含至少一个元素。");

            if (StableKeys == null || StableKeys.Count == 0)
                errors.Add("Keys 集合不能为空且必须包含至少一个元素。");

            // 验证字符串属性
            if (string.IsNullOrWhiteSpace(TypeName))
                errors.Add("TypeName 不可为空或空字符串。");

            // 验证 ID
            if (ID == 0)
                errors.Add("ID 不可为零。");

            // 其他可选的验证规则
            // 例如，验证 FileInertvaWidth 是否在合理范围内
            // if (FileInertvaWidth < 0 || FileInertvaWidth > 1)
            //     errors.Add("FileInertvaWidth 必须在 0 和 1 之间。");

            // 返回是否通过所有验证
            return errors.Count == 0;
        }


        //public double GetTotalArea()
        //{
        //    var measureData = this.Points.Select(T => new Measuring.MeasurData(T.X, T.Y)).ToList();

        //    var measuring = new ClsMyMeasuring(measureData, this.FileInertvaWidth)
        //    {
        //        XReference = Convert.ToSingle(this.XReference)
        //    };
        //    return measuring.LeftArea + measuring.RightArea;

        //}
        //public double GetLeftArea()
        //{
        //    var measureData = this.Points.Select(T => new Measuring.MeasurData(T.X, T.Y)).ToList();

        //    var measuring = new ClsMyMeasuring(measureData, this.FileInertvaWidth)
        //    {
        //        XReference = Convert.ToSingle(this.XReference)
        //    };
        //    return measuring.LeftArea;
        //}

        //public double GetRightArea()
        //{
        //    var measureData = this.Points.Select(T => new Measuring.MeasurData(T.X, T.Y)).ToList();

        //    var measuring = new ClsMyMeasuring(measureData, this.FileInertvaWidth)
        //    {
        //        XReference = Convert.ToSingle(this.XReference)
        //    };
        //    return measuring.RightArea;
        //}
    }

    // Class representing a point in the [Points] section
    public class Point
    {
        public int Index { get; set; }
        public float X { get; set; }
        public float Y { get; set; }
    }

    // Class representing a measure key in the [MeasureKeys] section
    public class MeasureKey
    {
        public double Coordinate { get; set; }
        public double Value { get; set; }
    }
    // Class representing a key in the [Keys] section
    public class StableKeys
    {
        public double Coordinate { get; set; }
        public double Value { get; set; }
    }

}
